#include <iostream>
#include <string>
#include <stdlib.h>
#include <unistd.h>
#include <vector>
#include <sys/wait.h>
#include <sys/types.h>
namespace MyShell
{
    class myshell
    {
        typedef std::string str;
        typedef std::vector<str> vv;
    public:
        myshell()
            :_lastcode(0)
            ,_cease(0)
            ,_sizeargv(0)
            ,_sizeenv(0)
        {
            _argv.resize(5);
            _env.resize(5);
            _path = getenv("PWD");
            _UserHName += getenv("USER");
            _UserHName += "@";
            _UserHName += getenv("HOSTNAME");
        }
        
        void run()
        {
            _cease = 1;
            while(_cease)
            {
                //打印命令行
                Print();
                //读取命令行参数
                readcomd();
                //判断是否退出
                Exit();
                //执行命令
                runcomd();

            }
        }


    private:
        void runcomd()
        {
            //判断命令类型
            bool je = judgecom();
            //执行普通命令
            if(!je)normalcmd();
            //清空_argv
            for(size_t i = 0;i <= _sizeargv;i++)_argv[i].clear();
            _sizeargv = 0;
        }

        void normalcmd()
        {
            //创建子进程进行程序替换
            pid_t id = fork();
            if(id == 0)
            {
                str s;
                for(size_t i = 0;i <= _sizeargv;i++)s+=_argv[i];
                // execvipe()
                //std::cout << _argv[0] << " " << s << std::endl;
                execlp(_argv[0].c_str(),s.c_str());
                exit(errno); 
            }
            else if(id < 0)
            {
                //创建子进程失败
            }
            else 
            {
                int status =  0;
                pid_t ret = waitpid(id,&status,0);
                if(ret == id)
                {
                    _lastcode = WEXITSTATUS(status);
                }
            }

        }
        

        bool judgecom()
        {
            
            if(_sizeargv == 1 && _argv[0] == "cd")
            {
                char cwd[1024];
                chdir(_argv[1].c_str());
                getcwd(cwd,sizeof(cwd));
                _path = cwd;
                
                sprintf(getenv("PWD"),"%s",cwd);
            //  std::cout << cwd << std::endl;
                return true;
            }
            else if(_sizeargv == 1 && _argv[0] == "echo")
            {
                if(_argv[1] == "&?")
                {
                    std::cout << _lastcode << std::endl;
                    _lastcode = 0;
                }
                else if(_argv[1][0] == '&')
                {
                    char * val = getenv(_argv[1].c_str()+1);
                    std::cout << val << std::endl;
                }
                else 
                {
                    std::cout << _argv[1] << std::endl;
                }
                return true;
            }
            else if(_sizeargv == 1 && _argv[0] == "exprot")
            {
    
            }

            if(_argv[0] == "ls" || _argv[0] == "ll")
            {
                if(_argv[0] == "ll")
                {
                    _argv[0] = "ls";
                    _argv.push_back("-l");
                }
            }


            return false;
        }

        void Exit()
        {
            if(_argv[0] == "exit")exit(1);    
        }

        void Print()
        {
            std::cout << "[" << _UserHName << " " << _path << "]" << "#";
        }
        void readcomd()
        {
            str tmp;
            std::getline(std::cin,tmp);
            str s;
            for (size_t i = 0; i < tmp.size(); i++)
            {
	            if (tmp[i] != ' ' && tmp[i] != '\t')
	            {
		            s = tmp.substr(i);
                    break;
        	    }
            }
            //std::cout << s.size()  << std::endl;
            //字符串分割
            for(size_t i = 0;i < s.size();i++)
            {
                if(s[i] == ' ' || s[i] == '\t')
                {
                    while(i < s.size() && (s[i] == ' ' || s[i] == '\t'))i++;
                    if(i != s.size())_sizeargv++;
                    i--;
                }
                else
                {
                    if(_sizeargv >= _argv.size()) _argv.resize(_argv.size()*2);
                    //if(s[i]=='\n'){_argv[cnt].push_back('\0');break;}   
                    _argv[_sizeargv].push_back(s[i]);
                   //printf("_argv[%d].push_back()->%c\n",_sizeargv,s[i]);
                }   
            }
            //for(size_t j = 0;j <= _sizeargv;j++)
            //{
            //    std::cout << _argv[j];
            //}
        }

        int _lastcode;//子进程退出码
        int _cease;//
        size_t _sizeargv;//
        size_t _sizeenv;
        vv _argv;//
        vv _env;//
        str _path;//
        str _UserHName;//
       
    };

}
